package com.hyt.it.ogt.opertaion.track.aspect;

import com.hyt.core.util.StringUtils;
import com.hyt.it.ogt.opertaion.track.annotations.OtherTrackLogSave;
import com.hyt.it.ogt.opertaion.track.aspect.base.BaseServiceAspect;
import com.hyt.it.ogt.opertaion.track.model.OtherLogVO;
import com.hyt.it.ogt.opertaion.track.queue.OperationTrackBlockQueue;
import com.hyt.it.ogt.opertaion.track.util.BeanUtils;
import com.hyt.it.ogt.opertaion.track.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 朱振宇
 * @since 2022/11/13
 */
@Slf4j
@Aspect
@Order
@Component
@ConditionalOnProperty(value = "otherLogAspect.enabled", havingValue = "true", matchIfMissing = true)
public class OtherLogAspect extends BaseServiceAspect {

    // 配置织入点
    @Pointcut("execution(* *(..)) && @annotation(otherTrackLogSave)")
    public void statisticsPointCut(OtherTrackLogSave otherTrackLogSave) {
    }

    /**
     * 处理完请求后执行
     *
     * @param joinPoint 切点
     */
    @AfterReturning(pointcut = "statisticsPointCut(otherTrackLogSave)", returning = "jsonResult")
    public void doAfterReturning(JoinPoint joinPoint, OtherTrackLogSave otherTrackLogSave, Object jsonResult) {
        handleStatistics(joinPoint, otherTrackLogSave, jsonResult);
    }

    protected void handleStatistics(final JoinPoint joinPoint, OtherTrackLogSave otherTrackLogSave, Object jsonResult) {
        try {
            boolean push = saveByJoinPoint(joinPoint, otherTrackLogSave) || saveByJsonResult(jsonResult, joinPoint, otherTrackLogSave);
            /*if (log.isDebugEnabled()) {
                log.debug("其它轨迹日志推送:{}", push);
            }*/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void execute(List<Map<String, Object>> fieldValMaps, Annotation annotation) {
        List<OtherLogVO> otherLogVOList = BeanUtils.convertMapToBeanList(fieldValMaps, OtherLogVO.class);
        String beginTime = DateUtils.nowMillSecond();
        OtherTrackLogSave otherTrackLogSave = (OtherTrackLogSave) annotation;
        otherLogVOList.forEach(vo -> {
            if (!StringUtils.isEmpty(otherTrackLogSave.eventTypeValue())) {
                vo.setEventType(Integer.valueOf(otherTrackLogSave.eventTypeValue()));
            }
            if (!StringUtils.isEmpty(otherTrackLogSave.operateTypeValue())) {
                vo.setOperateType(Integer.valueOf(otherTrackLogSave.operateTypeValue()));
            }
            if (!StringUtils.isEmpty(otherTrackLogSave.operateUserValue())) {
                vo.setOperateUser(otherTrackLogSave.operateUserValue());
            } else if (Objects.isNull(vo.getOperateUser())) {
                vo.setOperateUser(getUserId());
            }
            if (!StringUtils.isEmpty(otherTrackLogSave.beginTimeValue())) {
                vo.setBeginTime(otherTrackLogSave.beginTimeValue());
            } else if (Objects.isNull(vo.getBeginTime())) {
                vo.setBeginTime(beginTime);
            }
        });
        OperationTrackBlockQueue.producer(otherLogVOList);
        //String token = getToken();
        /*OperationTrackExecutorFactory.getThreadPoolExecutor().execute(()-> {
            if(token != null) {
                OperationTrackFeignInterceptor.setOperationTrackThreadLocal(HEADER_TOKEN, token);
            }
            ksOperationTrackClient.saveOtherTrackLog(otherLogVOList);
        });*/
    }
}
